package sfs

import (
	"encoding/json"
	"wzgames/pkg/utils/stringutil"
)

// RawPacket 数据包
type RawPacket struct {
	Id        uint16 // action id
	ControlId uint8
	Content   []byte
	Pooled    bool // 是否是pool出来的，方便返回池子
}

func (m *RawPacket) Write(p []byte) (int, error) {
	m.Content = append(m.Content, p...)
	return len(p), nil
}

// 数据格式详见 smartfoxserver.com

// DataWrapper 数据单元
type DataWrapper struct {
	DataType uint8       `json:"data_type"`
	Data     interface{} `json:"data"`
}

// TSfsObject SFSObject
type TSfsObject struct {
	Data map[string]DataWrapper `json:"data"`
}

func (m *TSfsObject) GetID() uint16 {
	return m.GetUint16(ActionId)
}

func (m *TSfsObject) GetControlID() uint8 {
	return m.GetByte(ControllId)
}

func (m *TSfsObject) GetContent() *TSfsObject {
	return m.GetSFSObject(ParamId)
}

func (m *TSfsObject) IsNull(key string) bool {
	if v, ok := m.Data[key]; !ok {
		return true
	} else {
		return v.Data == nil
	}
}

func (m *TSfsObject) GetByte(key string) uint8 {
	if v, ok := m.Data[key]; !ok {
		return 0
	} else {
		if v.Data == nil {
			return 0
		}
		r, ok := v.Data.(uint8)
		if ok {
			return r
		}
		return 0
	}
}

func (m *TSfsObject) GetBool(key string) bool {
	if v, ok := m.Data[key]; !ok {
		return false
	} else {
		if v.Data == nil {
			return false
		}
		r, err := stringutil.ToBoolean(v.Data)
		if err == nil {
			return r
		}
		return false
	}
}

func (m *TSfsObject) GetUint16(key string) uint16 {
	if v, ok := m.Data[key]; !ok {
		return 0
	} else {
		if v.Data == nil {
			return 0
		}
		r, ok := v.Data.(uint16)
		if ok {
			return r
		}
		return 0
	}
}

func (m *TSfsObject) GetUtfString(key string) string {
	if v, ok := m.Data[key]; !ok {
		return ""
	} else {
		if v.Data == nil {
			return ""
		}
		return stringutil.ToString(v.Data)
	}
}

func (m *TSfsObject) GetUint32Array(key string) []uint32 {
	if v, ok := m.Data[key]; !ok {
		return nil
	} else {
		if v.Data == nil {
			return nil
		}
		if v.DataType != IntArray {
			return nil
		}
		op, ok := v.Data.([]uint32)
		if ok {
			return op
		}
		return nil
	}
}

func (m *TSfsObject) GetInt32Array(key string) []int32 {
	if v, ok := m.Data[key]; !ok {
		return nil
	} else {
		if v.Data == nil {
			return nil
		}
		if v.DataType != IntArray {
			return nil
		}
		op, ok := v.Data.([]int32)
		if ok {
			return op
		}
		return nil
	}
}

func (m *TSfsObject) GetLongArray(key string) []int64 {
	if v, ok := m.Data[key]; !ok {
		return nil
	} else {
		if v.Data == nil {
			return nil
		}
		if v.DataType != LongArray {
			return nil
		}
		op, ok := v.Data.([]int64)
		if ok {
			return op
		}
		return nil
	}
}

func (m *TSfsObject) GetShortArray(key string) []uint16 {
	if v, ok := m.Data[key]; !ok {
		return nil
	} else {
		if v.Data == nil {
			return nil
		}
		if v.DataType != ShortArray {
			return nil
		}
		op, ok := v.Data.([]uint16)
		if ok {
			return op
		}
		return nil
	}
}

func (m *TSfsObject) GetSFSObject(key string) *TSfsObject {
	if v, ok := m.Data[key]; !ok {
		return nil
	} else {
		if v.DataType != SfsObject {
			return nil
		}
		r, ok1 := v.Data.(*TSfsObject)
		if ok1 {
			return r
		}
		r1, ok1 := v.Data.(TSfsObject)
		if ok1 {
			return &r1
		}
		return nil
	}
}

func (m *TSfsObject) ToJson() []byte {
	b, _ := json.Marshal(m)
	return b
}

// TSfsArray SFSArray
type TSfsArray struct {
	Data []DataWrapper `json:"data"`
}
